package com.mengtian_tech.smart_farm.vo;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mengtian_tech.smart_farm.controller.HomeController;
import com.mengtian_tech.smart_farm.model.BaseInfo;
import com.mengtian_tech.smart_farm.model.BaseModel;

public class Query<T> {
	private static final Logger logger = LoggerFactory
			.getLogger(HomeController.class);
	
	private Class<T> clazz;
	
	private boolean includeDeleted = false; //默认查询的结果不包含删除的信息
	
	/**
	 * 查询条件，比如 [name="fda",age=10,num>12] 
	 */
	private List<String> wheres = new LinkedList<String>();
	private List<Object> whereValues = new LinkedList<Object>();
	
	/**
	 * 排序，比如 [name desc,createDate asc] 
	 */
	private List<String> orders = new ArrayList<String>();
	
	/**
	 * 每页条数
	 */
	private int pageSize = 10;
	/**
	 * 当前页
	 */
	private int pageNo = 1; 
	/**
	 * 总条数
	 */
	private long total = 0; 
	
	
	public Query(Class<T> clazz) {
		this.clazz = clazz;
	}
	
	/**
	 * 获取最多的记录数，默认为10条
	 * @param clazz
	 * @param pageSize
	 */
	public Query(Class<T> clazz,int pageSize) {
		this.clazz = clazz;
		this.pageSize = pageSize;
	}

	public Class<T> getClazz() {
		return clazz;
	}
	
	 

	
	public void addOrder(String order,String direction) {
		this.orders.add(order + " " + direction);
	}
	
	
	/**
	 * 获取查询的hql语句
	 */
	public String getQueryString() {
		StringBuilder builder = new StringBuilder();
		
		builder.append(" select a from ");
		builder.append(this.clazz.getSimpleName());
		builder.append(" a ");
		
		//构造where查询
		builder.append(" where  1=1 ");
		
		if(BaseModel.class.isAssignableFrom(this.clazz)) {//如果是baseModel的子类
			if(!this.includeDeleted) {
				builder.append(" and a.deleted = 0 ");
			}
		}
		
		for(String where:wheres) {
			where = where.trim();
			builder.append(" and a.");
			builder.append(where);
		}
		
		//构造排序字段
		for(String order : orders) {
			order = order.trim();
			builder.append(" order by a.");
			builder.append(order);
		}		
		return builder.toString();
	}
	
	/**
	 * 获取总数的查询语句
	 */
	public String getCountString() {
		StringBuilder builder = new StringBuilder();
		
		builder.append(" select count(a) from ");
		builder.append(this.clazz.getSimpleName());
		builder.append(" a ");
		
		//构造where查询
		builder.append(" where  1=1 ");
		
		if(BaseModel.class.isAssignableFrom(this.clazz)) {//如果是baseModel的子类
			if(!this.includeDeleted) {
				builder.append(" and a.deleted = 0 ");
			}
		}
		
		for(String where:wheres) {
			where = where.trim();
			builder.append(" and a.");
			builder.append(where);
		}
		
		return builder.toString();
	}

	public boolean isIncludeDeleted() {
		return includeDeleted;
	}

	public void setIncludeDeleted(boolean includeDeleted) {
		this.includeDeleted = includeDeleted;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getPageNo() {
		return pageNo;
	}

	public void setPageNo(int pageNo) {
		this.pageNo = pageNo;
	}

	public long getTotal() {
		return total;
	}

	public void setTotal(long total) {
		this.total = total;
	}
	
	public static <T> Query<T> create(Class<T> clazz) {
		return new Query<T>(clazz);
	}
	
	public static <T> Query<T> create(Class<T> clazz,Integer pageNo,Integer pageSize) {
		Query<T> q =  new Query<T>(clazz);
		if(pageNo == null) {
			q.setPageNo(1);
		}else {
			q.setPageNo(pageNo);
		}
		
		if(pageSize == null) {
			q.setPageSize(100);
		}else {
			q.setPageSize(pageSize);
		}
		
		return q;
	}
	
	public static <T extends BaseModel> Query<T> create(T obj) {
		
		 return create(obj,obj.getPageNo(),obj.getPageSize());
	}
	 
	private static <T> Query<T> create(T obj,Integer pageNo,Integer pageSize) {
		Query<T> q =  new Query<T>( (Class<T>) obj.getClass());
		if(pageNo == null) {
			q.setPageNo(1);
		}else {
			q.setPageNo(pageNo);
		}
		
		if(pageSize == null) {
			q.setPageSize(100);
		}else {
			q.setPageSize(pageSize);
		}
		
		//自动组装查询条件
		try {
			installWheres(q,obj);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		
		return q;
	}

	private  static <T> void installWheres(Query<T> q, T obj) throws IllegalArgumentException, IllegalAccessException {
		Field[] fields =  obj.getClass().getDeclaredFields();
		System.out.println("get fields:"+fields.length);
		for(Field field : fields) {
			field.setAccessible(true);
			String fieldType = field.getType().getName();
			if("java.lang.String".equals(fieldType)) {
				Object value = field.get(obj);
				if(value != null) {
					q.like(field.getName(), value);
				}
			} 
		}
	}

	

	public List<Object> getWhereValues() {
		return whereValues;
	}
	
	public static void main(String args[]) throws IllegalArgumentException, IllegalAccessException {
		BaseInfo info = new BaseInfo();
		info.setName("测试");
		Query<BaseInfo> q = new Query<BaseInfo>(BaseInfo.class);
		installWheres(q, info);
		
		System.out.println(q.getWhereValues());
	}

	/**
	 * 不等于
	 * @param string
	 * @param id
	 */
	public void notEq(String filedName, String value) {
		int index = this.whereValues.size()+1;
		this.wheres.add(filedName + " != ?"+index);
		this.whereValues.add(value);
	}
	
	
	/**
	 * 添加等于的查询条件
	 */
	public Query<T> eq(String filedName,Object value) {
		int index = this.whereValues.size()+1;
		this.wheres.add(filedName + " = ?"+index);
		this.whereValues.add(value);
		return this;
	}
	
	public void isNull(String filedName) {
		this.wheres.add(filedName + " = null");
	}
	
	public void like(String name, Object value) {
		int index = this.whereValues.size()+1;
		this.wheres.add(name + " like ?"+index);
		this.whereValues.add("%"+value+"%");
		
	}
	
	public void between(String name,Object begin,Object end) {
		int index = this.whereValues.size()+1;
		this.wheres.add(name + " >= ?"+index);
		this.whereValues.add(begin);
		
		index = this.whereValues.size()+1;
		this.wheres.add(name + " <= ?"+index);
		this.whereValues.add(end);
		
	}
}
